import numpy as np
from Kohonen.fuzzydist import fuzzyDist


def transToMatrix(array):
    matrix = np.zeros([1, len(array)])
    for i in range(len(array)):
        matrix[0, i] = array[i]
    return matrix


def fcm(data, C):
    M = 2
    N, S = data.shape
    Iter = 0
    P = np.zeros([C, S])
    Dist = np.zeros([C, N])
    U = np.zeros([C, N])
    # 随机初始化划分矩阵
    U0 = np.random.rand(C, N)
    U0 = U0 / (np.ones([C, 1]).dot(transToMatrix(np.sum(U0, axis=0))))

    # FCM的迭代算法
    while True:
        # 迭代计数器
        Iter = Iter + 1
        # 计算或更新聚类中心P
        Um = np.power(U0, M)
        P = Um.dot(data) / np.transpose((np.ones([S, 1])).dot(np.sum(np.transpose(Um))))
        # 更新划分矩阵U
        for i in range(C):
            for j in range(N):
                Dist[i, j] = fuzzyDist(P[i], data[j])

        U = np.power(np.power(Dist, M) * np.dot(np.ones([C, 1]), transToMatrix(np.sum(np.power(Dist, -M), axis=0))), -1)
        # FCM算法迭代停止条件
        pauRes = np.linalg.norm(U - U0, ord=np.inf)
        if pauRes < 1.0e-4 or Iter > 0:
            break
        U0 = U

    return P, U